<?php
namespace Hive;
use Doctrine\DBAL\Connection;
use Fox\Dao\Link;
use Fox\Dao\SqlFragment;
use Hive\Ressource\Wish;
use Hive\Ressource\Reminder;
use Hive\Ressource\Experience;
use Fox\Common\Address;
use Fox\Object\Links;
/**
 * Ressource Object.
 *
 * It represant a Human Ressource.
 *
 * @author Xavier VILAIN
 * @package ressource
 * @property int 	$ressource_id 	Ressource Id
 * @property string	$status			Status
 * @property string $last_name		Last Name
 * @property string $firs_name		First Name
 * @property string $gender			Gender
 * @property date 	$birth_date 	Birth Date
 * @property int 	$kn_number_year Knowledge number of year
 * @property date 	$kn_udate		Knowledge Update Date
 * @property string $email			Email
 * @property int 	$adrid			Address Id (can be null)
 * @property bool 	$loekz 			Deletion Flag if true is an been deleted
 * 
 * @method array wishes()
 * @method array experiences()
 * @method array interviews()
 * @method array missions()
 */
class Ressource extends \Fox\Object\Versioned
{
	/**
	 *
	 * Short Cut to handle uri.
	 * @var string
	 */
	const BUNDLE_NAME = 'ressource';

	/**
	 * Join Documents
	 * @var array
	 */
	public static $JOIN_RESUME = array(
		'source' => 'ressources',
		'table' => 'ressource_documents',
		'short' => 'res',
		'foreign' => 'ressource_id',
		'column' => 'ressource_id',
		'type' => 'INNER JOIN');

	/**
	 * Join Experiences
	 * @var array
	 */
	public static $JOIN_EXPERIENCES = array(
		'source' => 'ressources',
		'table' => 'ressource_experiences',
		'short' => 'exp',
		'foreign' => 'ressource_id',
		'column' => 'ressource_id',
		'type' => 'INNER JOIN');

	/**
	 * Join Interviews
	 * @var array
	 */
	public static $JOIN_INTERVIEWS = array(
		'source' => 'ressources',
		'table' => 'ressource_interviews',
		'short' => 'intv',
		'foreign' => 'ressource_id',
		'column' => 'ressource_id',
		'type' => 'INNER JOIN');

	public static $LEFTJOIN_INTERVIEWS = array(
		'source' => 'ressources',
		'table' => 'ressource_interviews',
		'short' => 'intv',
		'foreign' => 'ressource_id',
		'column' => 'ressource_id',
		'type' => 'LEFT JOIN');

	public static $JOIN_DESIRE = array(
		'source' => 'ressources',
		'table' => 'ressource_desires',
		'short' => 'des',
		'foreign' => 'ressource_id',
		'column' => 'ressource_id',
		'type' => 'INNER JOIN');

	public static $JOIN_MISSIONS = array(
		'source' => 'missions',
		'table' => 'mission_partners',
		'short' => 'pa',
		'foreign' => 'missionid',
		'column' => 'missionid',
		'type' => 'INNER JOIN');

	public static $JOIN_MISSION_PARTNERS = array(
		'source' => 'ressources',
		'table' => 'mission_partners',
		'short' => 'pa',
		'foreign' => 'partnerid',
		'column' => 'ressource_id',
		'type' => 'INNER JOIN');
	
	/**
	 * Link To Personnal Address
	 */
	const LINK_ADDRESS = 'address';

	/**
	 * Link To All Address links
	 */
	const LINK_ADDRESSES = 'addresses';
	
	/**
	 * Link to Ressource
	 * @var unknown_type
	 */
	const LINK_RESSOURCE = 'ressource';

	/**
	 * Link To Experiences
	 * @var string
	 */
	const LINK_EXPERIENCES = 'experiences';

	/**
	 * Link To wishes
	 * @var string
	 */
	const LINK_WISHES = 'wishes';
	
	/**
	 * Link To Interviews
	 * @var string
	 */
	const LINK_INTERVIEWS = 'interviews';
	
	/**
	 * Link To External Source Of Data
	 * @var string
	 */
	const LINK_SOURCES = 'sources';

	/**
	 * Link To Skills
	 * @var string
	 */
	const LINK_SKILLS =  'skills';

	/**
	 * Link to the ressource todo reminder
	 * @var string
	 */
	const LINK_REMINDER = 'reminder';

	/**
	 * Link to Group
	 * @var string
	 */
	const LINK_GROUP = 'group';

	/**
	 * Link to the ressource todo reminder
	 * @var string
	 */
	const LINK_DOCUMENTS = 'documents';

	/**
	 * Link To Experiences
	 * @var string
	 */
	const LINK_MISSIONS = 'missions';

	/**
	 * Link to notes
	 * @var string
	 */
	const LINK_NOTES = 'notes';

	/**
	 * Link to notes
	 * @var string
	 */
	const LINK_PARTNERS = 'partners';

	/**
	 * Reverse link for any object
	 * @var string
	 */
	const LINK_CONTACT = 'contact';

	/**
	 * Link to mailbox messages
	 * @var string
	 */
	const LINK_MESSAGES = 'messages';
		
	/**
	 * Document Type Grouping
	 * @var int
	 */
	const DOC_GROUPING = 'ca';
	
	/**
	 * Document Type Grouping
	 * @var int
	 */
	const DOC_TYPE_DEFAULT = 'cv';
	
	/**
	 * Changing Experiences
	 * @var string
	 */
	const CHANGE_EXPERIENCES = 'experiences';

	/**
	 * Changing Interviews
	 * @var string
	 */
	const CHANGE_INTERVIEWS = 'interviews';

	/**
	 * Add an Interview
	 * @var string
	 */
	const CHANGE_INTERVIEW_ADD = 'add-interview';

	/**
	 * Add an Interview
	 * @var string
	 */
	const CHANGE_INTERVIEW_DELETE  = 'del-interview';
		
	/**
	 * Changing Documents
	 * @var string
	 */
	const CHANGE_DOCUMENTS = 'documents';

	/**
	 * Changing wishes
	 * @var string
	 */
	const CHANGE_WISHES = 'wishes';
	
	/**
	 * Adding a new wish
	 * @var string
	 */
	const CHANGE_WISH_ADD = 'add-wish';
	
	/**
	 * Changing wishes
	 * @var string
	 */
	const CHANGE_WISHES_DELETE = 'del-wishes';
	
	/**
	 * Changing Documents
	 * @var string
	 */
	const CHANGE_DOCUMENT_DELETE = 'rm-document';

	/**
	 * Adding a new Experience
	 * @var string
	 */
	const CHANGE_EXPERIENCE_ADD = 'add-experience';

	/**
	 * Delete an Experience
	 * @var string
	 */
	const CHANGE_EXPERIENCE_DELETE = 'del-experience';
	
	/**
	 * Delete an Experience
	 * @var string
	 */
	const CHANGE_IMPORT = 'import';
	
	/**
	 * Changing Status
	 * @var string
	 */
	const CHANGE_STATUS_ONLY = 'status-only';
		
	/**
	 * Contact Type Lead
	 * @var string
	 */
	const TYPE_LEAD = 'lead';
	
	/**
	 * Contact Type Customer
	 * @var string
	 */
	const TYPE_CUSTOMER = 'cust';
	
	/**
	 * Contact Type Customer
	 * @var string
	 */
	const TYPE_MIXED = 'mixed';
	
	/**
	 *
	 * Status New :
	 * @var string
	 */
	const STATUS_NEW = 1;

	/**
	 * Status Work In Progress :
	 * @var string
	 */
	const STATUS_WIP = 8;

	/**
	 * Status Validated :
	 * @var string
	 */
	const STATUS_VALIDATED = 99;

	/**
	 * Professional Address
	 * @var string
	 */
	const ADDRESS_PRO = 2;
	
	/**
	 * Personal Address
	 * @var string
	 */
	const ADDRESS_PERSO = 1;
	
	/**
	 * Task Reference Type equal to Ressource
	 * @var int
	 */
	const TASK_REFERENCE = 1;
	
	/**
	 * Contact Message Reference
	 * @var int
	 */
	const MESSAGE_REFERENCE = 1;
	
	/**
	 * Authorization for Self Validation, if the
	 * user has this authorization, the status goes from
	 * New to Valid automaticaly
	 * @var string
	 */
	const AUTH_STATUS_SELF_VALID = 'hive-status-self-va';

	/**
	 * Authorization for Validation, if the user has this authorization,
	 * the status can be change from WP to VA by the user.
	 * @var string
	 */
	const AUTH_STATUS_CAN_VALID = 'hive-status-can-va';

	/**
	 * Authorization for Validation, if the user has this authorization,
	 * the status can be change from WP to VA by the user.
	 * @var string
	 */
	const AUTH_GROUP_CAN_CHG = 'hive-group-chg';

	/**
	 * Creation Type :
	 * Standard means it's a classic contact creation from the 
	 * creation form
	 * @var int
	 */
	const CREATION_TYPE_STANDARD = 1;
	
	/**
	 * Creation Type :
	 * Resumes means the contact has been created using 'Import Resume'
	 * interface
	 * @var int
	 */
	const CREATION_TYPE_RESUMES = 2;

	/**
	 * Creation Type data source :
	 * LinkedIn means the contact has been created using 'Import File'
	 * interface with a LinkedIn exported file
	 * @var int
	 */
	const CREATION_TYPE_LINKEDIN = 3;

	/**
	 * Creation Type data source :
	 * Viadeo means the contact has been created using 'Import File'
	 * interface with a Viadeo exported file
	 * @var int
	 */
	const CREATION_TYPE_VIADEO = 4;
	
	/**
	 * Creation Type data source :
	 * Hive File means the contact has been created using 'Import File'
	 * interface with a Hive Custom file
	 * @var int
	 */
	const CREATION_TYPE_HIVE_FILE = 5;
	
	/**
	 * Creation Type data source :
	 * Website means the contact has been created through web service call
	 * @var int
	 */
	const CREATION_TYPE_WEBSITE = 6;

	/**
	 * 
	 * Creation Type data source : user mailbox
	 * @var int
	 */
	const CREATION_TYPE_EMAIL = 7;
	
	/**
	 * Source: user mailbox
	 * @var int
	 */
	const SOURCE_EMAIL = 1;
	
	/**
	 * Source: user mailbox
	 * @var int
	 */
	const SOURCE_CORPORATE_WEBSITE = 5;
	
		
	/**
	 * Unique Reference Id when uploading a file
	 * @var int
	 */
	const REFERENCE_UPLOAD = 1;
	
	/**
	 *
	 * Current Experience
	 * @var Hive\Ressource\Experience
	 */
	private $currentExperience = null;

	/**
	 *
	 * List of Previous Jobs
	 * @var array of Hive\Ressource\Experience
	 */
	private $experiences = null;

	/**
	 * Interviews
	 * @var array
	 */
	private $wish = null;

	/**
	 *
	 * Name of the school
	 * @var string
	 */
	private $school = null;

	/**
	 * List of open tasks on the contact
	 * @var array
	 */
	private $tasks = null;

	/**
	 * List Of Additionnal Addresses
	 * @var array
	 */
	private $_additionnalAddresses = null;
	
	/**
	 *
	 * @param array $fields
	 */
	protected function afterSetFields(array $fields)
	{
		if(!empty($fields['schoolid']) && empty($fields['school']))
		{
			$school = \Fox\Dao::load(School::className(),$fields['schoolid']);
			$this->school = $school->sch_name;
		}
		foreach($this->getProtectedFields() as $fieldName => $value)
		{
			unset($fields[$fieldName]);
		}
		unset($fields['adrid']);
		if(!empty($fields['postal_code'])) {
			$fields['stateid'] = substr($fields['postal_code'],0,2);
		}
		try {
			$this->address()->setFields($fields);	
		} catch(\Fox\Object\Exception\NotExist $e) {
			\Fox\Message::Warning($e->getMessage());
		}
	}

	
	/**
	 * Find all associated tasks 
	 * @return array
	 */
	public function tasks($displayDelete = false)
	{
		if(empty($this->tasks))
		{
			$finder = \Fox\Dao::finder(\Shama\Task::className())
							->orderBy('duedate','DESC');
			if(!$displayDelete)	{
				$finder->where('status != ?',array(\Shama\Task::STATUS_CLOSED));
			}			
							
			$finder->follow(\Shama\Task::LINK_REFERENCES)
								->where('reference = ? AND reference_id= ?',
									array(self::TASK_REFERENCE,$this->ressource_id));
			$this->tasks = $finder->find();
		}
		return $this->tasks;
	}
	
	/**
	 * @return string First and Last name
	 */
	public function name() {
		return $this->first_name.' '.$this->last_name;
	}

	/**
	 * This method is used to standardize CRUD behavior
	 */
	public function label() {
		return $this->name();
	}
	
	/**
	 * Retrieve all ressource (including Address,Experience)
	 * @return array
	 */
	public function getData()
	{
		$data = parent::getData();
		if(empty($this->school) && !empty($data['schoolid']) )
		{
			$school = \Fox\Dao::load(School::className(),$data['schoolid']);
			$this->school = $school->sch_name;
		}
		$data['school'] = $this->school;
		return array_merge($this->address()->getData(),$data);
	}


	/**
	 * (non-PHPdoc)
	 * @see Fox\Object.Versioned::beforeVersionCreate()
	 */
	protected function beforeVersionCreate() {
		// Status Management
		$this->manageStatusWorkflow();
		// Handle Knowledge Years
		$this->kn_udate = self::sqlDateTime(time());
	}

	/**
	 * (non-PHPdoc)
	 * @see includes/classes/Fox/Object/Versioned::afterVersionCreate()
	 */
	protected function afterVersionCreate(\Fox\Version $version)
	{
		// Add to the search engine
		$searchEngine = new \Fox\SearchEngine();
		$searchEngine->add($this,$this->getId(),self::className());
		if(!empty($this->_additionnalAddresses)) {
			foreach($this->_additionnalAddresses as $addressData) {
				$addressLink = new Ressource\Address();
				$addressLink->address()->setFields($addressData);
				$addressLink->type = self::ADDRESS_PRO;
				$addressLink->ressource_id = $this->getId();
				$addressLink->create();
				unset($addressLink);
			}
		}
	}

	/**
	 * (non-PHPdoc)
	 * @see Fox\Object.Versioned::beforeVersionUpdate()
	 */
	protected function beforeVersionUpdate($changed) {
		if(!empty($this->changes['kn_number_year'])) {
			$this->kn_udate = self::sqlDateTime(time());
		}
		return $changed;
	}
	
	/**
	 * (non-PHPdoc)
	 * @see includes/classes/Fox/Object/Versioned::afterVersionUpdate()
	 */
	protected function afterVersionUpdate()
	{
		if($this->isChangeType(self::CHANGE_DEFAULT)) {
			$searchEngine = new \Fox\SearchEngine();
			$searchEngine->synchronize($this,$this->getId(),self::classname());
		}
	}

	/**
	 * 
	 * Add Address to a contact
	 * @param \Fox\Common\Address $address
	 */
	public function additionnalAddresses($address) {
		$this->_additionnalAddresses[] = $address;
	}
	
	/**
	 *
	 * Change Status to next Step
	 * @return string New Status
	 */
	public function manageStatusWorkflow()
	{
		$status = $this->status;
		// Status Management
		if(empty($status) || $status == self::STATUS_VALIDATED || $status == self::STATUS_WIP )
		{
			if(\Fox\Authorization\Manager::check(self::AUTH_STATUS_SELF_VALID))
			{
				$this->status = self::STATUS_VALIDATED;
			}
		}
		return $this->status;
	}

	/**
	 *
	 * Upload a new resume end attach it to the ressource
	 * @param array $file
	 */
	public function uploadDocument($documentToSearchEngine = true)
	{
		$fileName = \Xview::moveFileToServer();
		$data['filename'] = $fileName['filename'];
		$data['destination'] = _TEMP_;
		$data['language'] = 'fr';
		$data['doctype'] = Ressource\Document::TYPE_RESUME;
		$data['physicalname'] = $fileName['physicalname'];
		// Create Document Object
		$document = new \Fox\Document();
		$document->setFields($data);
		$document->create();
		// Create Document Link
		$resData['ressource_id'] = $this->getId();
		$resData['docid'] = $document->getId();
		$resume = new Ressource\Document();
		$resume->setFields($resData);
		$resume->create();
		// Add Document to the search engine
		if($documentToSearchEngine)
		{
			$searchEngine = new \Fox\SearchEngine();
			$searchEngine->add($document,$this->getId(),self::classname());
		}
	}

	/**
	 * @return string Ressource language
	 */
	public function language()	{
		return \Xview::instance()->language();//@FIXME add language in the field list
	}

	/**
	 * Return Contact age in year
	 * @return int
	 */
	public function age()
	{
		$birthDate = $this->birth_date;
		if(!empty($birthDate) && $birthDate != '0000-00-00')
		{
			$birthDate = new \DateTime($birthDate);
			$today = new \DateTime();
			$interval = $birthDate->diff($today);
			return $interval->format('%y');
		}
		return null;
	}
	
	/**
	 * Gender
	 * @return string
	 */
	public function gender() {
		return $this->gender;
	}
	
	/**
	 * Use for the Search Engine
	 * @return string All object attributes has a string
	 */
	public function content()
	{
		$data = array('first_name' => $this->first_name,
				'last_name' => $this->last_name,
				'gender' => $this->gender,
				'birth_date' => $this->birth_date,
				'email' => $this->email,
				);
		$schoolid = $this->schoolid;
		$scholar = $this->scholar;
		if(!empty($schoolid)) {
			$data['school'] = \Fox\Dao::load(School::className(),$schoolid)->sch_name;
		}
		$data['scholar'] = empty($scholar) ? null : \Fox\Ddic\DataElement\Text::label('scholar',$scholar);
		// Address Information
		$address = $this->address();
		$data['phone1'] = str_replace(array('.','-','_'),' ',$address->phone1);
		$data['phone1s'] = str_replace(' ','',$data['phone1']);
		$data['phone2'] = str_replace(array('.','-','_'),' ',$address->phone2);
		$data['phone2s'] = str_replace(' ','',$data['phone2']);
		$data['zipcode'] = $address->postal_code;
		$data['city'] = $address->city;
		$data['street'] = $address->street;
		$data['country'] = $address->country;
		$data['country'] = empty($data['country']) ? null : \Fox\Ddic\DataElement\Text::label('country',$data['country']);
		return implode(',',$data);
	}

	/**
	 * Load all available resume
	 */
	public function resumes() {
		$finder = new Ressource\Document();
		$res = $finder->find(new \Fox\Dao\SqlFragment('ressource_id = ?',array($this->getId())));
		foreach($res as $resumeLink)
		{
			$documentIds[] = $resumeLink->docid;
		}
		if(!empty($documentIds))
		{
			$finder = new \Fox\Document();
			$res = $finder->find(new \Fox\Dao\SqlFragment('docid IN (?)',
							array($documentIds),
							array(\Doctrine\DBAL\Connection::PARAM_STR_ARRAY)));
			return $res;

		}
		return null;
	}

	/**
	 * Ressource current wish
	 * @return
	 */
	public function wish() {
		if(empty($this->wish))
		{
			$this->wish = new Wish();
			foreach($this->wishes() as $wish) {
				$this->wish = $wish;
				break;
			}
		}
		return $this->wish;
	}

	/**
	 * Check if the contact is a customer
	 * @return bool
	 */
	public function isCustomer()
	{
		return $this->isTypeOf(self::TYPE_CUSTOMER);
	}
	
	/**
	 * Check if the contact is a lead
	 * @return bool
	 */
	public function isLead()
	{
		return $this->isTypeOf(self::TYPE_CUSTOMER);
	}
	
	/**
	 * Check if the contact is a mixed of types
	 * @return bool
	 */
	public function isMixed()
	{
		return $this->isTypeOf(self::TYPE_MIXED);
	}
	
	/**
	 * Check if the contact type
	 * @return bool
	 */
	public function isTypeOf($type)
	{
		if($this->type == $type)
		{
			return true;
		}
		return false;
	}
	
	/**
	 *
	 * Find and Retrieve current position, if none is found it will
	 * return an empty position
	 * @return Experience
	 */
	public function currentPosition()
	{
		if(empty($this->currentExperience))
		{
			foreach($this->experiences() as $experience) {
				$this->currentExperience = $experience;
				break;
			}
		}
		// If no experience loaded
		if(empty($this->currentExperience))
		{
			$this->currentExperience = new Ressource\Experience();
		}
		return $this->currentExperience;
	}

	/**
	 * (non-PHPdoc)
	 * @see Fox\Object\Versioned::delete()
	 */
	public function delete()
	{
		$handle = \Fox\Dao::infos(self::className())->handle();
		$handle->beginTransaction();
		// Mark Document has deleted
		$resumes = $this->resumes();
		if(is_array($this->resumes())) {
			foreach($this->resumes() as $resume)
			{
				$resume->delete();
			}
		}
		// Remove Mission Links
		$missions = \Fox\Dao::finder(Mission\Partner::className())
						->where('partnerid = ?',array($this->ressource_id))
						->find();
		foreach($missions as $missionLink) {
			$missionLink->delete();
		}
		// Delete Tasks
		foreach($this->tasks() as $task) {
			$task->delete();
		}
		// Remove All Search Help matches
		$searchEngine = new \Fox\SearchEngine();
		$searchEngine->deleteMatchesByGrouping($this);

		parent::delete();
		$handle->commit();
	}

	/**
	 *
	 * @return array List of Mission where the user has been assigned
	 */
	public function missions($force = false)
	{
		if(empty($this->missions) || $force) {
			$finder = new Mission();
			$this->missions = $finder->find(new \Fox\Dao\SqlFragment('partnerid = ? AND role = ?',array($this->getId(),Mission\Partner::ROLE_CANDIDATE)),
											array('pa.udate' => 'DESC'),
											array(self::$JOIN_MISSIONS)
											);
		}
		return $this->missions ;
	}

	/**
	 * Mission Count
	 * Count the number of assigned mission
	 * @return int
	 */
	public function missionsCount()	{
		$info = \Fox\Dao::infos(\Hive\Mission\Partner::className());
		$query = $info->handle()->createQueryBuilder();
		$query->select('COUNT(*) as nb')
				->from($info->tableName(),'t')
				->innerJoin('t','missions','m','t.missionid = m.missionid');
		$fragment = new SqlFragment('t.partnerid = ? AND t.role = ? AND m.loekz = ?',array($this->getId(),Mission\Partner::ROLE_CANDIDATE,0));
		return $fragment->pushIn($query)->execute()->fetchColumn();
	}

	/**
	 * 
	 * Enter description here ...
	 * @param unknown_type $missionId
	 */
	public function findMission($missionId) {
		if(empty($missionId)) {
			return false;
		}
		$finder = new Mission();
		$missions = $finder->find(new \Fox\Dao\SqlFragment('t.missionid = ? AND partnerid = ? ',array($missionId,$this->getId())),
								null,
								array(self::$JOIN_MISSIONS));
		if(count($missions) == 1) {
			return $missions[0];
		} else {
			return false;
		}
		
	}
	/**
	 *
	 * Enter description here ...
	 */
	public function situation()
	{
		return $this->currentPosition()->jobtitle;
	}

	/**
	 * Determine the number of years of experience
	 * @return int
	 */
	public function yearsOfExperience()
	{
		return $this->kn_number_year;
	}

	/**
	 * Build a news stream based on every events attached to the contact
	 * Enter description here ...
	 */
	public function news()
	{
		$news = array();
		// Load all jobs experience
		foreach($this->experiences() as $job)
		{
			if(!$job->exists())
				continue;
			$news[$job->start_date] = array(
				'type' => $job::className(),
				'object' => $job);
		}
		// Load all wishes
		foreach($this->wishes() as $wish)
		{
			if(!$wish->exists())
				continue;
			$news[$wish->cdate] = array(
				'type' => $wish::className(),
				'object' => $wish);
		}
		// Load all open tasks
		foreach($this->tasks() as $task)
		{
			if(!$task->exists())
				continue;
			$news[$task->duedate] = array(
				'type' => $task::className(),
				'object' => $task);
		}
		// Load all open missions
		foreach($this->missions() as $mission)
		{
			$partner =  $mission->partnerLink($this->getId());
			$date = $partner->cdate;
			if(empty($date))
				$date = $mission->cdate;
			$news[$date] = array(
				'type' => $mission::className(),
				'object' => $mission);
		}

		asort($news);
		return $news;
	}
	
	/**
	 * Find default note object
	 * @return Ressource\Note
	 */
	public function note() {
		$finder = new Ressource\Note();
		$res = $finder->find(new SqlFragment('ressource_id = ? AND type = ?',
				array($this->ressource_id,
					Ressource\Note::TYPE_DEFAULT)));
		if(count($res) > 0) {
			return $res[0];
		} else {
			return $finder;
		}
	}
	
	/**
	 * Return Contact Primary Email
	 * @todo
	 * @return string
	 */
	public function primaryEmail() {
		return $this->email;
	}
	
	/**
	 * 
	 * Find all contact with passed email
	 * @param array	$emails
	 * @return array
	 */
	public static function findEmailDuplicates($emails = null) {
		if(!is_array($emails)) {
			$emails = array($emails);
		}
		$query = \Fox\Dao::infos(self::className())->handle()->createQueryBuilder();
		$query->select('t.ressource_id','t.last_name','t.first_name','t.email AS email','ad.email1 AS email1')
				->from('ressources','t')
				->leftJoin('t','address','ad','t.adrid = ad.adrid');
		$fragments[] = new SqlFragment('t.loekz = 0 AND ( t.email IN (?) OR ad.email1 IN (?) )',
							array(	$emails,
									$emails),
							array(	Connection::PARAM_STR_ARRAY,
									Connection::PARAM_STR_ARRAY)
							);	
		$fragment = SqlFragment::combine($fragments);
		$res = $fragment->pushIn($query)->execute()->fetchAll(\PDO::FETCH_ASSOC);
		return $res;
	}

	/**
	 * Get Contact full name
	 * @param int $id
	 * @return array
	 */
	public static function fullName($id) {
		$query =  \Fox\Dao::infos(self::className())->handle()
				->createQueryBuilder()
				->select('t.first_name','t.last_name')
				->from('ressources','t');
         $fragment = new \Fox\Dao\SqlFragment('t.ressource_id = ?',array($id));
         $res = $fragment->pushIn($query)->execute()->fetchAll(\PDO::FETCH_NUM);
         if(count($res) == 1) {
        	return $res[0][0].' '.$res[0][1];
         } else {
        	return null;
         }
	}
	
	/**
	 * 
	 * Parse a full name into first and last name
	 * @param string $fullname
	 * @return array
	 */
	public static function parseFullName($fullname) {
		$parts = explode(' ',$fullname);
		$nbOfParts = count($parts);
		if($nbOfParts == 1 ) {
			return array('last_name' => $parts[0]);
		} elseif($nbOfParts == 2) {
			return array(
					'first_name' => $parts[0],
					'last_name' => $parts[1]
					);
		} else {
			// Check if one of the word is uppercase
			$first_name = $last_name = null;
			for($i=0;$i<$nbOfParts;$i++) {
				$alreadyInsert = false;
				if(strtoupper($parts[$i]) == $parts[$i]) {
					$last_name .= $parts[$i].' ';
					$alreadyInsert = true;
				}
				if(!empty($last_name) ) {
					if(!$alreadyInsert) {
						$last_name .= $parts[$i].' ';
					}
				} else {
					$first_name .= $parts[$i].' ';
				}
			}
			return array(
					'first_name' => trim($first_name),
					'last_name' => trim($last_name)
					);
		}
	}
	
	/**
	 * 
	 * Return Custom Hive contact label generator for messages
	 * 
	 * @return Fox\Generator
	 */
	public static function labelGenerator() {
		return \Fox\Generator::useFunction(function($data) {
			// Check for Reference ?
			if(empty($data['reference'])) {
				if($data['reference_class_id'] == \Orx\Mailer\MailBox\Message::MAILBOX_REFERENCE) {
					try {
						$mailbox = \Fox\Dao::load(\Orx\User\MailBox::className(),$data['idusr'].':'.$data['boxid']);
						$output = '<span class="label label-important" title="'.$data['email'].'">'.$mailbox->name.'</span>';
					} catch(\Fox\Object\Exception\NotExist $e) {
						$output = '<span class="label label-important" title="'.$data['email'].'">'.$data['email'].'</span>';
					}
					
				} else {
					$findedInDB = \Hive\Ressource::findEmailDuplicates($data['email']);
					if(count($findedInDB) == 1 ) {
						$output = '<a class="label label-info haslink" href="?mod=ressource&act=main&rid='.$findedInDB[0]['ressource_id'].'&area=messages" title="'.$data['email'].'">'.$findedInDB[0]['first_name'].' '.$findedInDB[0]['last_name'].'</a>';
					} elseif(count($findedInDB) > 1) {
						$output = '<span class="label label-warning" title="'.$data['email'].'">'.$findedInDB[0]['first_name'].' '.$findedInDB[0]['last_name'].'</span>';
					} else {
						$name = !empty($data['name']) ?  $data['name'] : $data['email'];
						$output = '<span class="label" title="'.$data['email'].'">'.$name.'</span>';
					}
				}
			}  else {
				$output = '<a class="label label-success haslink" href="?mod=ressource&act=main&rid='.$data['reference'].'&area=messages" title="'.$data['email'].'">'.$data['name'].'</a>';
			}
			return $output;
		});
	}
	
	/**
	 * 
	 * Return Custom Hive contact label title generator for messages
	 * to display missions assignment
	 * @return Fox\Generator
	 */
	public static function titleGenerator() {
		return \Fox\Generator::useFunction(function($message) {
			$output = null;
			foreach($message->labels() as $label) {
				if($label->reference_class_id == \Hive\Mission::MESSAGE_REFERENCE) {
					$designation = \Hive\Mission::reference($label->reference);
					if(!empty($designation)) {
						$link = '?mod=missions&act=main&area=messages&missionid='.$label->reference;
						$inlineid = $label->getInLineId();
						
						$title = Msg(\Hive::BUNDLE,\Hive::GO_TO_X,$designation);
						$output .= '<span class="label label-inverse" id="ref_'.$label->reference.'">';
						$output .= '<a  href="'.$link.'" class="hastooltip" title="'.$title.'" style="font-size: 10px;margin-right: 2px;">'.$designation.'</a>';
						$title = Msg(\Hive::BUNDLE,\Hive::REMOVE_THIS_LABEL);
						$output .= '<a  href="?" title="'.$title.'" class="remove hastooltip action {\'target\':\'?mod=messages&act=labels&sac=unassign&inlineid='.$inlineid.'\',\'message\':\'true\',\'remove\':\'ref_'.$label->reference.'\'}">&times;</a>';
						$output .= '</span>';
					}
				}
			}
		
			return $output;
		});
	}
	
	/**
	 * Get Contact Picture Url
	 * @return string
	 */
	public function picture() {
		if($this->picture !== null) {
			return _APPLICATION_IMAGES_PROFILE_URL_.'thumb_'.$this->picture;
		} else {
			return _APPLICATION_DEFAULT_PROFILE_PICTURE_;
		}
		
	}
}
\Fox\Dao::infos(Ressource::className(),new \Fox\Object\Info('ressources', \Fox\Databases::DB_APP));

// Link To ?
Links::add(\Fox\Dao::link(Reminder::className(), Reminder::LINK_RESSOURCE)
	->to(Ressource::className(),Ressource::LINK_REMINDER)
	->on('ressource_id')
	->oneToOne()
	->linkOnly()
);
// Link To Personnal Address
\Fox\Object\Links::add(\Fox\Dao::link(Ressource::className(),Ressource::LINK_ADDRESS,Link::FETCH_EAGER)
	->to(Address::className(), Ressource::LINK_RESSOURCE)
	->on('adrid')
	->oneToOne()
	->versionTo()
);
// Link To Other Addresses
\Fox\Object\Links::add(\Fox\Dao::link(Ressource\Address::className(),Ressource\Address::LINK_RESSOURCE)
	->to(Ressource::className(), Ressource::LINK_ADDRESSES)
	->on('ressource_id')
	->versionFrom()
);
// Link To External Source of Information
\Fox\Object\Links::add(\Fox\Dao::link(Ressource\Source::className(),Ressource\Source::LINK_RESSOURCE)
	->to(Ressource::className(), Ressource::LINK_SOURCES)
	->on('ressource_id')
	->versionFrom()
);
// Link To Documents (Resume...)
\Fox\Object\Links::add(\Fox\Dao::link(Ressource\Document::className(),Ressource\Document::LINK_RESSOURCE)
	->to(Ressource::className(), Ressource::LINK_DOCUMENTS)
	->on('ressource_id')
	->versionFrom()
);
// Link To Skills
\Fox\Object\Links::add(\Fox\Dao::link(Ressource\Skill::className(),Ressource\Skill::LINK_RESSOURCE)
	->to(Ressource::className(), Ressource::LINK_SKILLS)
	->on('ressource_id')
	->versionFrom()
);
// Link to Groups
Links::add(\Fox\Dao::link(Ressource::className(),Ressource::LINK_GROUP)
	->to(Ressource\Group::className(),Ressource\Group::LINK_RESSOURCE)
	->on('grouping')
	->oneToOne()
	->linkOnly()
);
// Link To Experiences
\Fox\Object\Links::add(\Fox\Dao::link(Ressource\Experience::className(),Ressource\Experience::LINK_RESSOURCE)
	->to(Ressource::className(), Ressource::LINK_EXPERIENCES)
	->on('ressource_id')
	->orderBy('start_date','DESC')
	->versionFrom()
);
// Link To Wishes
\Fox\Object\Links::add(\Fox\Dao::link(Ressource\Wish::className(),Ressource\Wish::LINK_RESSOURCE)
	->to(Ressource::className(), Ressource::LINK_WISHES)
	->on('ressource_id')
	->orderBy('cdate','DESC')
	->versionFrom()
);
// Link To Interviews
\Fox\Object\Links::add(\Fox\Dao::link(Ressource\Interview::className(),Ressource\Interview::LINK_RESSOURCE)
	->to(Ressource::className(), Ressource::LINK_INTERVIEWS)
	->on('ressource_id')
	->orderBy('plan_date','DESC')
	->versionFrom()
);
// Link To Notes
\Fox\Object\Links::add(\Fox\Dao::link(Ressource\Note::className(),Ressource\Note::LINK_RESSOURCE)
	->to(Ressource::className(), Ressource::LINK_NOTES)
	->on('ressource_id')
	->orderBy('udate','DESC')
	->versionFrom()
);

// Link To Partners
\Fox\Object\Links::add(\Fox\Dao::link(Ressource\Partner::className(),Ressource\Partner::LINK_RESSOURCE)
	->to(Ressource::className(), Ressource::LINK_PARTNERS)
	->on('ressource_id')
	->orderBy('role','ASC')
	->versionFrom()
);

// Link To Messages
\Fox\Object\Links::add(\Fox\Dao::link(\Orx\Mailer\MailBox\Message::className(),Ressource::LINK_CONTACT)
	->to(Ressource::className(), Ressource::LINK_MESSAGES)
	->on('reference')
	->orderBy('received_date','DESC')
);